//+------------------------------------------------------------------+
//|                  HistogramChart.mqh 柱状图绘图画布类头文件        |
//|                版权所有 2000-2025, MetaQuotes Ltd.              |
//|                        官方网址: https://www.mql5.com            |
//+------------------------------------------------------------------+
#include "ChartCanvas.h"         // 引入图表绘制基础类 CChartCanvas
#include <Arrays/ArrayObj.h>     // 引入对象数组类（用于存储多组柱状图数据）

//+------------------------------------------------------------------+
//| CHistogramChart 类                                                |
//| 功能：MT5 柱状图专用绘图画布类，基于图表基础类实现多系列柱状图渲染 |
//| 继承关系：public CChartCanvas（基于通用图表类，扩展柱状图特有能力）|
//| 核心特性：                                                      |
//|  1. 支持多数据系列柱状图（多组数据并列/堆叠显示）                  |
//|  2. 支持柱状图样式配置（渐变填充、间距、最小宽度、边框）          |
//|  3. 提供数据系列完整管理接口（添加、插入、更新、删除单条/单值）    |
//|  4. 继承基础图表的组件控制（轴、网格、图例等可见性）              |
//+------------------------------------------------------------------+
class CHistogramChart : public CChartCanvas
  {
private:
   //--- 柱状图样式相关参数
   uint              m_fill_brush[];     // 渐变填充画笔数组（存储柱状图渐变颜色的像素值）
   bool              m_gradient;         // 渐变填充标志（true 启用渐变，false 纯色填充，默认 true）
   uint              m_bar_gap;          // 柱子间距（像素，控制相邻柱子的横向间隔，默认 3）
   uint              m_bar_min_size;     // 柱子最小宽度（像素，避免柱子过窄无法显示，默认 5）
   uint              m_bar_border;       // 柱子边框宽度（像素，0 表示无边框，默认 0）

   //--- 数据存储参数
   CArrayObj        *m_values;           // 多系列数据存储指针（每个元素为 CArrayDouble，对应一组柱状图数据）

public:
   /**
    * @brief 构造函数：初始化柱状图绘图画布实例
    * @details 调用父类 CChartCanvas 构造函数，初始化柱状图样式默认值（渐变启用、间距3等），
    *          并默认显示图例、轴、网格（通过 ShowFlags 设置）
    */
                     CHistogramChart(void);

   /**
    * @brief 析构函数：销毁柱状图绘图画布实例
    * @details 释放渐变画笔数组资源，销毁父类管理的数据存储对象
    */
                    ~CHistogramChart(void);

   //--- 柱状图画布创建接口（重写父类方法，初始化数据存储）
   /**
    * @brief 创建柱状图画布资源（初始化尺寸、颜色格式，创建多系列数据存储对象）
    * @param name [in] 画布资源名称（用于标识图表对象）
    * @param width [in] 画布宽度（像素，必须 >0）
    * @param height [in] 画布高度（像素，必须 >0）
    * @param clrfmt [in] 颜色处理格式（默认 COLOR_FORMAT_ARGB_NORMALIZE，支持透明度）
    * @return bool - 操作结果：true 表示画布创建与数据存储初始化成功，false 表示失败
    * @note 内部会创建 CArrayObj 对象用于存储多组数据，并重写父类 m_data 指针指向该对象
    */
   virtual bool      Create(const string name,const int width,const int height,ENUM_COLOR_FORMAT clrfmt=COLOR_FORMAT_ARGB_NORMALIZE);

   //--- 柱状图样式配置接口（直接赋值，无需重绘触发）
   /**
    * @brief 设置是否启用柱子渐变填充
    * @param flag [in] 渐变标志：true 启用渐变，false 纯色填充（默认 true）
    * @note 需在绘制前设置，下次重绘时生效
    */
   void              Gradient(const bool flag=true) { m_gradient=flag;      }

   /**
    * @brief 设置柱子之间的间距（像素）
    * @param value [in] 间距值（>=0，默认 3，值越大柱子间隔越宽）
    * @note 需在绘制前设置，下次重绘时生效
    */
   void              BarGap(const uint value)       { m_bar_gap=value;      }

   /**
    * @brief 设置柱子最小宽度（像素）
    * @param value [in] 最小宽度（>=1，默认 5，避免柱子过窄无法显示）
    * @note 若计算出的柱子宽度小于该值，强制使用最小宽度
    */
   void              BarMinSize(const uint value)   { m_bar_min_size=value; }

   /**
    * @brief 设置柱子边框宽度（像素）
    * @param value [in] 边框宽度（0 表示无边框，默认 0）
    * @note 需在绘制前设置，下次重绘时生效，边框颜色使用父类的 m_color_border
    */
   void              BarBorder(const uint value)    { m_bar_border=value;   }

   //--- 数据系列管理接口（多组柱状图数据的增删改查）
   /**
    * @brief 添加一组柱状图数据（新数据系列，追加到末尾）
    * @param value [in] 数据数组（double 类型，每个元素对应一根柱子的数值）
    * @param descr [in] 数据系列描述符（图例中显示的名称，默认空字符串）
    * @param clr [in] 数据系列颜色（XRGB 格式，默认 0，自动分配默认颜色）
    * @return bool - 操作结果：true 表示添加成功，false 表示失败（如达到最大数据系列数）
    * @note 添加后会自动触发图表重绘，最大数据系列数由父类 m_max_data 控制（默认 10）
    */
   bool              SeriesAdd(const double &value[],const string descr="",const uint clr=0);

   /**
    * @brief 插入一组柱状图数据（在指定位置添加新数据系列）
    * @param pos [in] 插入位置索引（0 开始，需 < 当前数据系列数 m_data_total）
    * @param value [in] 数据数组（double 类型）
    * @param descr [in] 数据系列描述符（图例名称，默认空字符串）
    * @param clr [in] 数据系列颜色（XRGB 格式，默认 0，自动分配默认颜色）
    * @return bool - 操作结果：true 表示插入成功，false 表示失败（位置无效或达到最大数）
    * @note 插入后会自动触发图表重绘，后续数据系列索引自动后移
    */
   bool              SeriesInsert(const uint pos,const double &value[],const string descr="",const uint clr=0);

   /**
    * @brief 更新指定位置的数据系列（修改数据、描述符或颜色）
    * @param pos [in] 数据系列位置索引（0 开始，需 < m_data_total）
    * @param value [in] 新数据数组（double 类型，覆盖原数据）
    * @param descr [in] 新描述符（默认 NULL，不修改原描述符）
    * @param clr [in] 新颜色（XRGB 格式，默认 0，不修改原颜色）
    * @return bool - 操作结果：true 表示更新成功，false 表示失败（位置无效或数据错误）
    * @note 更新后会自动触发图表重绘
    */
   bool              SeriesUpdate(const uint pos,const double &value[],const string descr=NULL,const uint clr=0);

   /**
    * @brief 删除指定位置的数据系列
    * @param pos [in] 数据系列位置索引（0 开始，需 < m_data_total）
    * @return bool - 操作结果：true 表示删除成功，false 表示失败（位置无效）
    * @note 删除后会自动触发图表重绘，后续数据系列索引自动前移
    */
   bool              SeriesDelete(const uint pos);

   /**
    * @brief 更新单条数据（修改某组数据中指定位置的数值）
    * @param series [in] 数据系列索引（0 开始，需 < m_data_total）
    * @param pos [in] 数据在系列中的位置索引（0 开始，需 < 该系列数据长度）
    * @param value [in] 新数值（替换原位置的数值）
    * @return bool - 操作结果：true 表示更新成功，false 表示失败（系列/位置无效）
    * @note 更新后会自动触发图表重绘
    */
   bool              ValueUpdate(const uint series,const uint pos,double value);

protected:
   /**
    * @brief 绘制单组柱状图数据（重写父类纯虚方法，核心绘制逻辑）
    * @param idx [in] 数据系列索引（0 开始，对应 m_values 中的一组数据）
    * @note 内部逻辑：计算柱子位置与尺寸，调用 DrawBar 绘制单根柱子，支持渐变填充、数值标签显示
    */
   virtual void      DrawData(const uint idx);

   /**
    * @brief 绘制单根柱子（处理填充、边框）
    * @param x [in] 柱子左上角 X 坐标（像素）
    * @param y [in] 柱子左上角 Y 坐标（像素）
    * @param w [in] 柱子宽度（像素）
    * @param h [in] 柱子高度（像素，正数向上延伸，负数向下延伸）
    * @param clr [in] 柱子颜色（XRGB 格式，渐变时为基准色）
    * @note 根据 m_gradient 选择纯色填充或渐变填充，根据 m_bar_border 绘制边框
    */
   void              DrawBar(const int x,const int y,const int w,const int h,const uint clr);

   /**
    * @brief 创建渐变填充画笔（生成柱子渐变颜色的像素数组）
    * @param size [in] 画笔宽度（对应柱子宽度，像素）
    * @param fill_clr [in] 渐变基准颜色（XRGB 格式，渐变从该色向透明过渡）
    * @note 内部使用 Bresenham 圆算法生成径向渐变，结果存储在 m_fill_brush 数组中
    */
   void              GradientBrush(const int size,const uint fill_clr);
  };
//+------------------------------------------------------------------+